#ifndef LIBRARIAN_H_INCLUDED
#define LIBRARIAN_H_INCLUDED

#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#endif // LIBRARIAN_H_INCLUDED
#define HASH_TABLE_SIZE 1000
/** 借阅者结构体类型 **/
typedef struct reader{
    int readerId;               // 借阅者id
    char name[30];              // 借阅者姓名
} reader, *readerptr;           // 借阅者

/** 借阅记录结构类型 **/
typedef struct rcd{     
    readerptr reader;           // 借阅者
    char borrowTime[25];        // 借书时间
    char returnTime[25];        // 归还时间
} rcd, *rcdptr;       

/** 借阅记录的队列结点结构类型 **/
typedef struct rcdQueueNode{
    rcdptr data;                // 借阅记录的数据
    struct rcdQueueNode *next;  // 指向下一借阅记录的指针
} qNode;

/** 借阅记录队列结构类型 **/
typedef struct que{
    int count;                  // 借阅数量
    qNode *front;               // 头指针
    qNode *rear;                // 尾指针
} que, *queue;

/** 图书结构类型 **/
typedef struct book{
    int bookId;                 // 书号
    char name[30];              // 书名
    char writer[30];            // 著者
    int count;                  // 现存量
    int total;                  // 总库存量
    queue borrower;             // 借阅记录
} book, *bookptr;               // 结构体和指针的别名

/** 图书结点类型 **/
typedef struct bookNode{
    bookptr data;               // 图书数据
    struct bookNode *next;      // 指向下一结点指针
} bookNode, *bookNodeptr;

/** hash存储表结构 **/
typedef struct{
    bookNodeptr *rcd;           // 通过hash存放图书结点的数组
    int size;                   // 容量
    int count;                  // 已存在数
} HashTable, *Hashptr;

// 把整形(int)转换成字符串(char*)的形式
char *int2str(int num);

// 初始化队列
void initQueue(queue *q);

// 入队
int enQueue(queue q, rcdptr rdr);

// 出队
void deQueue(queue q);

// 获取队列头结点的数据
rcdptr getFront(queue q);

// 移除某借阅者id队列元素
int removeElem(queue q, int readerId);

// **********************

// 菜单
void menu();

// 清空缓冲区
void flush();

// 初始化图书信息
bookptr getBook(int bookId, char *name, char *writer, int total);

// 检查输入数据以及插入图书信息
int checkAndInsert(BTree *t, Hashptr table, KeyType k, void *rec);

// 打印所有图书信息
void printAllBook(BTree t);

// 打印所有图书信息功能类
void printBookIndex(BTree t);

// 打印图书详细信息
void printBookDetail(bookptr book);

// 打印单条图书信息
void printCompletBook(bookptr book);

// 打印单条图书信息2 差别只在于宽度
void printBook(bookptr book);

// 打印某著者的所有图书信息
int printBookByWriter(Hashptr table, char *name);

// 更新图书信息
int updateBook(Hashptr tb, bookptr book, char *nm, char *wrtr, int tot);

// 保存图书信息
void saveBTree(BTree t, FILE *index, FILE *queue);

// **********************

// 插入借阅者
int insertReader(BTree *t, void *rec);

// 打印所有借阅者信息
void printAllReader(BTree rt);

// 打印所有借阅者信息-功能函数
void printReaderIndex(BTree rt);

// 借书
int borrowBook(bookptr book, readerptr rdr);

// 还书
int returnBook(bookptr book, int readerid);

// 保存借阅者信息
void saveReader(BTree rt, FILE *fp_reader);

// **********************

// hash
int addHash(Hashptr table, bookptr book);

// hash函数
int hashFunc(char *data);

// 检测是否存在hash
int existHash(Hashptr table, bookptr book);

// 移除hash
int removeHash(Hashptr table, bookptr book);

// 拼接字符串
char *catchString(int n, ...);

// 写入日志
void writeLog(char *msg);

// 保存至文件
void save(BTree t, BTree rt);

// 从文件中加载数据
int load(BTree *t, BTree *rt, Hashptr tb);

// 从文件中加载借阅者数据
int loadReader(BTree *rt);

// 从文件中加载图书数据
int loadBTree(BTree *t, bookptr book);